Beispiel #1
0
void Arcball::init()
{
    center.set( 0.0, 0.0 );
    radius         = 1.0;
    q_now          = quat_identity();
    *rot_ptr       = identity3D();
    q_increment    = quat_identity();
    rot_increment  = identity3D();
    is_mouse_down  = false;
    is_spinning    = false;
    damp_factor    = 0.0;
    zero_increment = true;
}
Beispiel #2
0
		mat4 mat4::inverse(void)   // Gauss-Jordan elimination with partial pivoting
		{
			mat4 a(*this),	    // As a evolves from original mat into identity
			b(identity3D());   // b evolves from identity into inverse(a)
			int i, j, i1;

			// Loop over cols of a from left to right, eliminating above and below diag
			for (j=0; j<4; j++) {   // Find largest pivot in column j among rows j..3
			i1 = j;		    // Row with largest pivot candidate
			for (i=j+1; i<4; i++)
			if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
			i1 = i;

			// Swap rows i1 and j in a and b to put pivot on diagonal
			swap(a.v[i1], a.v[j]);
			swap(b.v[i1], b.v[j]);

			// Scale row j to have a unit diagonal
			if (a.v[j].n[j]==0.)
			VEC_ERROR("mat4::inverse: singular matrix; can't invert\n");
			b.v[j] /= a.v[j].n[j];
			a.v[j] /= a.v[j].n[j];

			// Eliminate off-diagonal elems in col j of a, doing identical ops to b
			for (i=0; i<4; i++)
			if (i!=j) {
			b.v[i] -= a.v[i].n[j]*b.v[j];
			a.v[i] -= a.v[i].n[j]*a.v[j];
			}
			}
			return b;
		}
Beispiel #3
0
void
c3arcball_init(
		c3arcballp a )
{
    a->center = c3vec2f( 0.0, 0.0 );
    a->radius         = 1.0;
    a->q_now          = c3quat_identity();
    a->rot_ptr		= &a->rot;
    a->rot   		= identity3D();
    a->q_increment    = c3quat_identity();
    a->rot_increment  = identity3D();
    a->is_mouse_down  = false;
    a->is_spinning    = false;
    a->damp_factor    = 0.0;
    a->zero_increment = true;
}
Beispiel #4
0
void static topBCall(Fl_Widget* w, void* v){
	UI* j = ((UI*)v);
	j->control->win->c->rot = identity3D();
	j->control->win->c->up = vec4(0, 1, 0, 1);
	j->control->win->c->eye = vec4(0, 0, 8, 1);
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	j->control->win->redraw();
}
Beispiel #5
0
void Arcball::mouse_down(int x, int y)
{
    down_pt.set( (float)x, (float) y );
    is_mouse_down = true;

    q_increment   = quat_identity();
    rot_increment = identity3D();
    zero_increment = true;
}
Beispiel #6
0
void 
ViewModel::reset() 
{
    up.set( 0.0, 1.0, 0.0 );

    eye.set(0.0,0.0,10.0);
    lookat.set(0.0,0.0,0.0);

    mtx = identity3D();

    update();
}
Beispiel #7
0
bool SceneInstance::computeTransform(mat4 &mat, int time)
{
    mat = identity3D();
    if (_transforms.empty())
        return false;
    else {
        for (vector<Transform*>::reverse_iterator it = _transforms.rbegin(); it != _transforms.rend(); ++it)
        {
            mat = mat * (**it).getMatrix(time);
        }
    }
    return true;
}
Beispiel #8
0
Viewport::Viewport(vec4 eye, int width, int height, Lens l) {
    _eye = eye;
	_UL = vec4(-0.18, 0.12, 1.02538, 0);
	_UR = vec4(0.18, 0.12, 1.02538, 0);
	_LL = vec4(-0.18, -0.12, 1.02538, 0);
	_LR = vec4(0.18, -0.12, 1.02538, 0);
    _pixelsWide = width;
    _pixelsHigh = height;
	_raysPerPixel = 1;
	_incPP = (int)sqrt((float)_raysPerPixel);
	_viewToWorld = identity3D();
	_lens = l;
}
Beispiel #9
0
void
c3arcball_mouse_down(
		c3arcballp a,
		int x,
		int y)
{
    a->down_pt = c3vec2f( (c3f)x, (c3f) y );
    a->is_mouse_down = true;

    a->q_increment   = c3quat_identity();
    a->rot_increment = identity3D();
    a->zero_increment = true;
}
Beispiel #10
0
Scene::Scene(char* path)
{
  shapes = new vector<Shape *>();
  lights = new vector<Light *>();
  
  outputPath = string("test.png");
  maxDepth = 5;
  attenuation[0] = 1.0;
  attenuation[1] = 0.0;
  attenuation[2] = 0.0;
  transformations.push(identity3D());
  ambient = Color(0.2, 0.2, 0.2);
  numSamples = 1;
  lensSize = 0;
  readScene(path);
  totalPix = width * height;
}
Beispiel #11
0
void Scene::readfile(char* file){
  string str, cmd; 
	vec3 ambient;
	vec3 diffuse;
  vec3 specular;
	double shininess;
	vec3 emission;
	vec3 attenuation = vec3(1,0,0);
	
	vector<vec3> vertices;
	
  ifstream in;
  in.open(file); 
  if (in.is_open()) {
		
   stack <mat4> transfstack; 
   transfstack.push(mat4(identity3D()));
	
	 getline (in, str); 
	 
   while (in) {
		 
		 
     if ((str.find_first_not_of(" \t\r\n") != string::npos) && (str[0] != '#')) {
       // Ruled out comment and blank lines 

       stringstream s(str);
       s >> cmd; 
       double values[10]; // Position and color for light, colors for others
       // Up to 10 params for cameras.  
       bool validinput; // Validity of input 

       if (cmd == "directional") {
         validinput = readvals(s, 6, values); // Position/color for lts.
         if (validinput) {
					 
					 vec3 posn = vec3(values[0],values[1],values[2]);
					 vec3 col = vec3(values[3],values[4],values[5]);
					 vec3 dir = vec3(transfstack.top() * vec4(posn, 0), 3);
					 Light light = Light(dir,col,0); 
					 
					 lights.push_back(light);

         
				 }
         
       }
			 
       else if (cmd == "point") {
         validinput = readvals(s, 6, values); // Position/color for lts.
         if (validinput) {
					 
					 vec3 posn = vec3(values[0],values[1],values[2]);
					 vec3 col = vec3(values[3],values[4],values[5]);
					 vec3 dir = vec3(transfstack.top() * vec4(posn, 1));
					 Light light = Light(dir,col,1,attenuation); 
					 
					 lights.push_back(light);

         
				 }
         
       }
       else if (cmd == "attenuation") {
         validinput = readvals(s, 3, values); // Position/color for lts.
         if (validinput) {
					 
					 attenuation = vec3(values[0],values[1],values[2]);

         
				 }
         
       }
			 
			 else if (cmd == "maxdepth") {
			 	validinput = readvals(s,1,values); 
			  if (validinput) { 
					maxdepth = values[0];
				} 
			}
			 
			 else if (cmd == "size") {
			 	validinput = readvals(s,2,values); 
			  if (validinput) { 
					pixels = vec2(values[0],values[1]);
					film = new Film(pixels); 
				} 
			}
			  else if (cmd == "output") {
			 		s>>name; 
				} 
			 	else if (cmd == "camera") {
Beispiel #12
0
mat4::mat4()
{
    *this = identity3D();
}
Beispiel #13
0
void World::loadInstance(SceneInstance *si) {

    // Compute transform information. Should add a mat4 even if there is no transform.
    mat4 mTransform;
    if (!si->computeTransform(mTransform)) {
        mTransform = identity3D(); // if there is no transform, push an identity matrix.
    }
    if (!transformStack.empty() && transformStack.top() != identity3D()) {
        mat4 mPreviousTransform = transformStack.top();
        mTransform =  mPreviousTransform * mTransform;
    }
    transformStack.push(mTransform);

    SceneGroup *sg = si->getChild();

    // Get camera info, if any.
    CameraInfo camInfo;
    if (sg->computeCamera(camInfo)) {
        vec4 eye(0.0, 0.0, 0.0, 1.0);
        double left = camInfo.sides[FRUS_LEFT];
        double right = camInfo.sides[FRUS_RIGHT];
        double top = camInfo.sides[FRUS_TOP];
        double bottom = camInfo.sides[FRUS_BOTTOM];
        double depth = -1*camInfo.sides[FRUS_NEAR];
        vec4 LL(left, bottom, depth, 1.0);
        vec4 UL(left, top, depth, 1.0);
        vec4 LR(right, bottom, depth, 1.0);
        vec4 UR(right, top, depth, 1.0);
        eye = mTransform * eye;
        LL = mTransform * LL;
        UL = mTransform * UL;
        LR = mTransform * LR;
        UR = mTransform * UR;
        _view = Viewport(eye, LL, UL, LR, UR, IMAGE_WIDTH, IMAGE_HEIGHT, camInfo.perspective);
    }

    // Compute light info, if any.
    LightInfo li;
    if (sg->computeLight(li)) {
        vec3 direction, position;
        switch (li.type) {
        case LIGHT_DIRECTIONAL:
        case LIGHT_POINT:
        case LIGHT_SPOT:
            direction = vec3(-1*mTransform[0][2],-1*mTransform[1][2],-1*mTransform[2][2]);
            position = mTransform * vec3(0.0);
            _lights[li.type].push_back(Light(position, direction, li));
            break;
        case LIGHT_AMBIENT:
            _ambientLight = li.color;
            break;
        }
    }

    // Computes sphere info, if any.
    double radius;
    MaterialInfo matInfo;
    if (sg->computeSphere(radius, matInfo, 0)) {
        _spheres.push_back(Sphere(vec4(0.0), radius, matInfo, mTransform));
    }

    // Recursively parse scene.
    for (int i = 0; i < sg->getChildCount(); i++) {
        loadInstance(sg->getChild(i));
    }

    // Pops the transformation matrix of this SceneGroup. This function should have added this matrix at the beginning.
    transformStack.pop();
}
Beispiel #14
0
		mat4::mat4(void) { *this = identity3D();}
Beispiel #15
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";
  }
}